import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpRequest;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;

/**
 * 描述：
 *
 * @author 🧑 ‍wanwei
 * @since 2025-08-16 14:44
 */
public class HttpTestCommon {

    //web-flux client 创建需要时间 比hutool慢 提前创建好
    private static final WebClient client = WebClient.builder()
            .baseUrl("http://localhost:8701")
            .defaultHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE)
            .build();

    public static void main(String[] args) throws InterruptedException {
        //hutool 工具类 request
        //httpRequest();
        //web-flux client
        //webClient();
        //webClient2();
        webClient3();
    }

    private static void webClient3() throws InterruptedException {
        System.out.println("webClient 测试开始 " + "----" + DateUtil.now() + "----" + Thread.currentThread());

        List<Flux<String>> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Flux<String> mono = client.get()
                    .uri("/test/hello")
                    .retrieve()
                    .bodyToFlux(String.class);
            list.add(mono);
        }
        //合并请求 可以实现多个请求并行 且在主线程中阻塞
        Flux<String> merged = Flux.merge(list);
        List<String> allResults = merged.collectList().block();

        allResults.forEach(s-> System.out.println(s + "----" + DateUtil.now() + "----" + Thread.currentThread()));
    }

    private static void webClient2() throws InterruptedException {
        System.out.println("webClient 测试开始 " + "----" + DateUtil.now() + "----" + Thread.currentThread());
        WebClient client = WebClient.builder()
                .baseUrl("http://localhost:8701")
                .build();
        List<Mono> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Mono<String> mono = client.get()
                    .uri("/test/hello")
                    .retrieve()
                    .bodyToMono(String.class);
            list.add(mono);
        }
        //block 会阻塞主线程 且每个请求会按照顺序阻塞执行
        for (Mono<String> mono : list) {
            String resp = mono.block(Duration.ofSeconds(10));
            System.out.println(resp + "----" + DateUtil.now() + "----" + Thread.currentThread());
        }
    }

    private static void webClient() throws InterruptedException {
        System.out.println("webClient 测试开始 " + "----" + DateUtil.now() + "----" + Thread.currentThread());
        WebClient client = WebClient.builder()
                .baseUrl("http://localhost:8701")
                .build();
        List<Mono> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Mono<String> mono = client.get()
                    .uri("/test/hello")
                    .retrieve()
                    .bodyToMono(String.class);
            list.add(mono);
        }
        //subscribe 并不会阻塞主线程 而是等到响应后自动触发 事件处理
        for (Mono mono : list) {
            mono.subscribe(s -> {
                //与主线程不是一个线程了
                System.out.println(s + "----" + DateUtil.now() + "----" + Thread.currentThread());
            });
        }

        Thread.sleep(10000);
    }

    private static void httpRequest() {
        System.out.println("hutool 测试开始 " + "----" + DateUtil.now());
        for (int i = 0; i < 3; i++) {
            String body = HttpRequest.get("http://localhost:8701/test/hello")
                    .execute()
                    .body();
            System.out.println(body + "----" + DateUtil.now());
        }
    }
}
